﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EventbriteService.Factory;
using EventbriteService.Util;

namespace EventbriteService.Adapter
{
    [CreateWithName(MessageFormat.JSON)]
    public class JsonAdapter:IDataAdapter
    {

        private IEventBriteData _root;

        public JsonAdapter(string doc)
        {
          //  doc = @"{""venue"":{""address"": {""address_1"": ""Lensfield Road"", ""address_2"": null, ""city"": ""Cambridge"", ""region"": null, ""postal_code"": ""CB2 1ER"", ""country"": ""GB"", ""latitude"": 52.1986648, ""longitude"": 0.12634990000003654}, ""resource_uri"": ""https://www.eventbriteapi.com/v3/venues/10491366/"", ""id"": ""10491366"", ""name"": ""Scott Polar Research Institute"", ""latitude"": ""52.1986648"", ""longitude"": ""0.12634990000003654""}}";
          
            var _document = new JsonReader(doc).Parse() as Dictionary<string, object>;
            _root = new Item( _document);
        }
        #region IDataAdapter Members

        public IEventBriteData Root
        {
            get { return _root; }
        }

        #endregion

        public bool IsErrorMessage()
        {
            return _root.Name == "error";
        }

        private class Item : IEventBriteData
        {
            List<IEventBriteData> _members;
            string _name;
            string _value;

            public Item(string name, string value)
            {
                _name = name;
                _value = value;
            }

            public Item(string name, ArrayList list)
            {
                _members = new List<IEventBriteData>();
                _name = name;
                foreach (var item in list)
                {
                    LoadList(item as Dictionary<string, object>);
                }
            }

            public Item(string name, Dictionary<string, object> elements)
            {
                _members = new List<IEventBriteData>();
                _name = name;
                LoadList(elements);
            }

            public Item(Dictionary<string, object> elements)
            {
                _members = new List<IEventBriteData>();
                foreach (var item in elements)
                {
                    _name = item.Key;
                    var val = item.Value;

                    if (val is ArrayList)
                    {
                        var list = val as ArrayList;
                        for (int i = 0; i < list.Count; i++)
                        {
                            LoadList(list[i] as Dictionary<string, object>);
                        }
                    }
                    else //if (val is Dictionary<string, object>)
                    {
                        //_name = item.Key;
                        LoadList(val as Dictionary<string, object>);

                    }
                    //else
                    //{
                    //    _members.Add(new Item(item.Key, val != null ? val.ToString() : null));
                    //}
                }
            }

            private void LoadList(Dictionary<string, object> item)
            {
                if (item == null)
                    return;
                
                foreach (var ele in item)
                {
                    if (ele.Value is Dictionary<string, object>)
                        _members.Add(new Item(ele.Key, ele.Value as Dictionary<string, object>));
                    else if (ele.Value is ArrayList)
                        _members.Add(new Item(ele.Key, ele.Value as ArrayList));
                    else
                        _members.Add(new Item(ele.Key, ele.Value != null ? ele.Value.ToString(): null));

                }
            }
           
            #region IEventBriteData Members

            public IEnumerable<IEventBriteData> Elements()
            {
                return _members;
            }

            public string Name
            {
                get
                {
                    return _name;
                }
                set
                {
                    _name = value;
                }
            }

            public string Value
            {
                get
                {
                    return _value;
                }
                set
                {
                    _value = value;
                }
            }

            #endregion
        }
    }
}
